//
//  NSNull+LCFMessageForwarding.m
//  JustForTest
//
//  Created by YaoZhaofeng on 16/1/19.
//  Copyright © 2016年 YaoZhaofeng. All rights reserved.
//

#import "NSNull+LCFMessageForwarding.h"
#import <objc/runtime.h>

@implementation NSNull (LCFMessageForwarding)
+ (void)load {
    static dispatch_once_t onceToken1;
    dispatch_once(&onceToken1, ^{
        Class class = [self class];
        
        SEL originalSelector = @selector(forwardInvocation:);
        SEL swizzledSelector = @selector(lcf_forwardInvocation:);
        
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        
        //首先动态添加方法，实现是被交换的方法，返回值表示添加成功还是失败
        BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
        if (success) {
            //如果成功，说明类中不存在这个方法的实现
            //将被交换方法的实现替换到这个并不存在的实现
            //ps. 应该是将不存在的方法实现替换到被交换的方法中
            class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        } else {
            //否则，交换两个方法的实现
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
    
    static dispatch_once_t onceToken2;
    dispatch_once(&onceToken2, ^{
        Class class = [self class];
        
        SEL originalSelector = @selector(methodSignatureForSelector:);
        SEL swizzledSelector = @selector(lcf_methodSignatureForSelector:);
        
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        
        BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
        if (success) {
            class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

#pragma mark - Method Swizzling

- (void)lcf_forwardInvocation:(NSInvocation *)anInvocation {
    if ([self respondsToSelector:anInvocation.selector]) {
        [anInvocation invokeWithTarget:self];
    }
    else{
        NSLog(@"找不到该方法，此处给忽略，不让崩溃");
    }
}

- (NSMethodSignature *)lcf_methodSignatureForSelector:(SEL)aSelector {
    NSMethodSignature *methodSignature = [NSNull instanceMethodSignatureForSelector:aSelector];
    if (methodSignature == nil) {
        methodSignature = [NSMethodSignature signatureWithObjCTypes:"@^v^c"];
    }
    return methodSignature;
}
@end
